// 玩家数据访问层

import { Player, Achievement } from '../../domain/models/Player';

/**
 * 玩家数据仓库接口
 */
export interface IPlayerRepository {
  /**
   * 保存玩家数据
   * @param player 玩家对象
   * @returns 保存后的玩家对象
   */
  save(player: Player): Promise<Player>;

  /**
   * 根据ID获取玩家
   * @param playerId 玩家ID
   * @returns 玩家对象，如果不存在则返回null
   */
  findById(playerId: number): Promise<Player | null>;

  /**
   * 获取所有玩家
   * @returns 玩家列表
   */
  findAll(): Promise<Player[]>;

  /**
   * 更新玩家数据
   * @param player 玩家对象
   * @returns 更新后的玩家对象
   */
  update(player: Player): Promise<Player>;

  /**
   * 删除玩家
   * @param playerId 玩家ID
   * @returns 是否删除成功
   */
  delete(playerId: number): Promise<boolean>;

  /**
   * 获取下一个可用的玩家ID
   * @returns 下一个玩家ID
   */
  getNextPlayerId(): Promise<number>;
}

/**
 * 内存玩家数据仓库实现
 * 注意：在实际应用中，这里应该实现与持久化存储（如数据库）的交互
 */
export class InMemoryPlayerRepository implements IPlayerRepository {
  private players: Map<number, Player> = new Map();
  private nextId: number = 1;

  /**
   * 保存玩家数据
   */
  async save(player: Player): Promise<Player> {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 100));
    
    // 如果是新玩家，分配ID
    if (player.id === 0) {
      player.id = this.nextId++;
    }
    
    // 保存到内存Map
    this.players.set(player.id, player);
    return player;
  }

  /**
   * 根据ID获取玩家
   */
  async findById(playerId: number): Promise<Player | null> {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 50));
    
    const player = this.players.get(playerId);
    // 返回深拷贝以避免直接修改内存中的对象
    return player ? this.deepCopyPlayer(player) : null;
  }

  /**
   * 获取所有玩家
   */
  async findAll(): Promise<Player[]> {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 100));
    
    // 返回所有玩家的深拷贝
    return Array.from(this.players.values()).map(player => this.deepCopyPlayer(player));
  }

  /**
   * 更新玩家数据
   */
  async update(player: Player): Promise<Player> {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 100));
    
    // 检查玩家是否存在
    if (!this.players.has(player.id)) {
      throw new Error(`Player with ID ${player.id} not found`);
    }
    
    // 更新玩家数据
    this.players.set(player.id, player);
    return this.deepCopyPlayer(player);
  }

  /**
   * 删除玩家
   */
  async delete(playerId: number): Promise<boolean> {
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 100));
    return this.players.delete(playerId);
  }

  /**
   * 获取下一个可用的玩家ID
   */
  async getNextPlayerId(): Promise<number> {
    return this.nextId;
  }

  /**
   * 创建玩家对象的深拷贝
   * @param player 要拷贝的玩家对象
   * @returns 玩家对象的深拷贝
   */
  private deepCopyPlayer(player: Player): Player {
    // 使用JSON序列化/反序列化进行深拷贝
    // 在实际应用中，可能需要更精细的拷贝逻辑
    const playerJson = JSON.stringify(player);
    const copiedPlayer = JSON.parse(playerJson);
    
    // 注意：如果Player类有方法或复杂对象引用，这里需要额外处理
    // 由于我们的Player类有方法，这里重新创建Player实例
    return new Player(
      copiedPlayer.id,
      copiedPlayer.name,
      copiedPlayer.avatar,
      copiedPlayer.level,
      copiedPlayer.experience,
      copiedPlayer.rank,
      copiedPlayer.joinDate,
      copiedPlayer.lastLoginDate,
      copiedPlayer.stats,
      copiedPlayer.skills,
      copiedPlayer.achievements
    );
  }
}

/**
 * 玩家仓库工厂
 * 用于创建玩家仓库实例
 */
export class PlayerRepositoryFactory {
  /**
   * 创建玩家仓库实例
   * @returns 玩家仓库实例
   */
  static createRepository(): IPlayerRepository {
    // 在实际应用中，可以根据配置创建不同的仓库实现
    // 例如：内存仓库、本地存储仓库、远程数据库仓库等
    return new InMemoryPlayerRepository();
  }
}